


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html id="htmlId">
<head>
  <title>Coverage Report :: AbstractDormancyUtils</title>
  <style type="text/css">
    @import "../../.css/coverage.css";
  </style>
</head>

<body>
<div class="header"></div>

<div class="content">
<div class="breadCrumbs">
    [ <a href="../../index.html">all classes</a> ]
    [ <a href="../index.html">at.dormancy.util</a> ]
</div>

<h1>Coverage Summary for Class: AbstractDormancyUtils (at.dormancy.util)</h1>

<table class="coverageStats">
<tr>
  <th class="name">Class</th>
<th class="coverageStat 
">
  Class, %
</th>
<th class="coverageStat 
">
  Method, %
</th>
<th class="coverageStat 
">
  Line, %
</th>
</tr>
<tr>
  <td class="name">AbstractDormancyUtils</td>
<td class="coverageStat">
  <span class="percent">
    100%
  </span>
  <span class="absValue">
    (1/ 1)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    100%
  </span>
  <span class="absValue">
    (11/ 11)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    97.7%
  </span>
  <span class="absValue">
    (42/ 43)
  </span>
</td>
</tr>

</table>

<br/>
<br/>


<div class="sourceCode"><i>1</i>&nbsp;/*
<i>2</i>&nbsp; * Copyright 2013 Gregor Schauer
<i>3</i>&nbsp; *
<i>4</i>&nbsp; * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
<i>5</i>&nbsp; * you may not use this file except in compliance with the License.
<i>6</i>&nbsp; * You may obtain a copy of the License at
<i>7</i>&nbsp; *
<i>8</i>&nbsp; *      http://www.apache.org/licenses/LICENSE-2.0
<i>9</i>&nbsp; *
<i>10</i>&nbsp; * Unless required by applicable law or agreed to in writing, software
<i>11</i>&nbsp; * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
<i>12</i>&nbsp; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<i>13</i>&nbsp; * See the License for the specific language governing permissions and
<i>14</i>&nbsp; * limitations under the License.
<i>15</i>&nbsp; */
<i>16</i>&nbsp;package at.dormancy.util;
<i>17</i>&nbsp;
<i>18</i>&nbsp;import at.dormancy.access.AbstractPropertyAccessStrategy;
<i>19</i>&nbsp;import at.dormancy.persistence.PersistenceUnitProvider;
<i>20</i>&nbsp;import org.springframework.beans.PropertyAccessor;
<i>21</i>&nbsp;import org.springframework.util.ReflectionUtils;
<i>22</i>&nbsp;
<i>23</i>&nbsp;import javax.annotation.Nonnull;
<i>24</i>&nbsp;import javax.annotation.Nullable;
<i>25</i>&nbsp;import javax.inject.Inject;
<i>26</i>&nbsp;import java.io.Serializable;
<i>27</i>&nbsp;import java.lang.annotation.Annotation;
<i>28</i>&nbsp;import java.lang.reflect.Method;
<i>29</i>&nbsp;import java.util.Collection;
<i>30</i>&nbsp;import java.util.HashMap;
<i>31</i>&nbsp;import java.util.Map;
<i>32</i>&nbsp;import java.util.Set;
<i>33</i>&nbsp;
<i>34</i>&nbsp;/**
<i>35</i>&nbsp; * Common utility methods for Dormancy support code.
<i>36</i>&nbsp; *
<i>37</i>&nbsp; * @author Gregor Schauer
<i>38</i>&nbsp; */
<i>39</i>&nbsp;public abstract class AbstractDormancyUtils&lt;PU, PC, PMD, PUP extends PersistenceUnitProvider&lt;PU, PC, PMD&gt;&gt; {
<b class="fc"><i>40</i>&nbsp;	protected static final Map&lt;Class&lt;?&gt;, AbstractPropertyAccessStrategy&gt; STRATEGY_MAP = new HashMap&lt;Class&lt;?&gt;, AbstractPropertyAccessStrategy&gt;();</b>
<i>41</i>&nbsp;	protected static final Class&lt;? extends Annotation&gt; idClass;
<i>42</i>&nbsp;	protected PUP persistenceUnitProvider;
<i>43</i>&nbsp;
<i>44</i>&nbsp;	static {
<b class="fc"><i>45</i>&nbsp;		String javaxPersistenceId = &quot;javax.persistence.Id&quot;;</b>
<b class="fc"><i>46</i>&nbsp;		idClass = ClassLookup.find(javaxPersistenceId).orThrow(&quot;Cannot find class: %s&quot;, javaxPersistenceId).get();</b>
<b class="fc"><i>47</i>&nbsp;	}</b>
<i>48</i>&nbsp;
<i>49</i>&nbsp;	@Inject
<b class="fc"><i>50</i>&nbsp;	protected AbstractDormancyUtils(@Nonnull PUP persistenceUnitProvider) {</b>
<b class="fc"><i>51</i>&nbsp;		this.persistenceUnitProvider = persistenceUnitProvider;</b>
<b class="fc"><i>52</i>&nbsp;	}</b>
<i>53</i>&nbsp;
<i>54</i>&nbsp;	/**
<i>55</i>&nbsp;	 * Iterates over the given collection, looking for an object which is semantically equal to a certain object.&lt;br/&gt;
<i>56</i>&nbsp;	 * An object is semantically equal if one of the following conditions apply:
<i>57</i>&nbsp;	 * &lt;ul&gt;
<i>58</i>&nbsp;	 * &lt;li&gt;the given object overrides the {@link #equals(Object)} equals methods, which returns {@code true} for
<i>59</i>&nbsp;	 * another object&lt;/li&gt;
<i>60</i>&nbsp;	 * &lt;li&gt;the given object has a non-null identifier and its type as well as the identifier value is equals to the
<i>61</i>&nbsp;	 * type and identifier value of another object&lt;/li&gt;
<i>62</i>&nbsp;	 * &lt;/ul&gt;
<i>63</i>&nbsp;	 *
<i>64</i>&nbsp;	 * @param obj        the object
<i>65</i>&nbsp;	 * @param collection the collection to traverse
<i>66</i>&nbsp;	 * @return the object found or {@code null} if the collection does not contain such an object
<i>67</i>&nbsp;	 * @see #getIdentifierValue(PMD, Object)
<i>68</i>&nbsp;	 */
<i>69</i>&nbsp;	@Nullable
<i>70</i>&nbsp;	@SuppressWarnings(&quot;unchecked&quot;)
<i>71</i>&nbsp;	public &lt;T&gt; T findPendant(@Nonnull T obj, @Nonnull Collection&lt;?&gt; collection) {
<b class="fc"><i>72</i>&nbsp;		Method method = ReflectionUtils.findMethod(getClass(obj), &quot;equals&quot;, Object.class);</b>
<b class="fc"><i>73</i>&nbsp;		if (method.getDeclaringClass() != Object.class) {</b>
<i>74</i>&nbsp;			// If the given object overrides the equals() method, invoke it for every object in the collection
<b class="fc"><i>75</i>&nbsp;			for (Object elem : collection) {</b>
<b class="fc"><i>76</i>&nbsp;				if (obj.equals(elem) &amp;&amp; collection.remove(elem)) {</b>
<b class="fc"><i>77</i>&nbsp;					return (T) elem;</b>
<i>78</i>&nbsp;				}
<b class="fc"><i>79</i>&nbsp;			}</b>
<i>80</i>&nbsp;		} else {
<i>81</i>&nbsp;			// Otherwise get the Hibernate metadata and a PropertyAccessor to get the identifier
<b class="fc"><i>82</i>&nbsp;			PMD objMetadata = getMetadata(obj);</b>
<b class="fc"><i>83</i>&nbsp;			Serializable objIdentifier = getIdentifier(objMetadata, obj);</b>
<i>84</i>&nbsp;
<i>85</i>&nbsp;			// For every object in the collection, check if the type matches and if the identifier is equal
<b class="fc"><i>86</i>&nbsp;			for (Object elem : collection) {</b>
<b class="fc"><i>87</i>&nbsp;				if (elem != null &amp;&amp; elem.getClass() == obj.getClass()</b>
<i>88</i>&nbsp;						&amp;&amp; objIdentifier.equals(getIdentifier(objMetadata, elem))
<i>89</i>&nbsp;						&amp;&amp; collection.remove(elem)) {
<b class="fc"><i>90</i>&nbsp;					return (T) elem;</b>
<i>91</i>&nbsp;				}
<b class="nc"><i>92</i>&nbsp;			}</b>
<i>93</i>&nbsp;		}
<b class="fc"><i>94</i>&nbsp;		return null;</b>
<i>95</i>&nbsp;	}
<i>96</i>&nbsp;
<i>97</i>&nbsp;	/**
<i>98</i>&nbsp;	 * Gets the persistence metadata associated with the given entity class.
<i>99</i>&nbsp;	 *
<i>100</i>&nbsp;	 * @param obj the object to retrieve ClassMetadata for
<i>101</i>&nbsp;	 * @return the ClassMetadata or {@code null} if the type is not an Hibernate managed entity
<i>102</i>&nbsp;	 * @see #getMetadata(Class)
<i>103</i>&nbsp;	 * @see #getClass(Object)
<i>104</i>&nbsp;	 */
<i>105</i>&nbsp;	@Nullable
<i>106</i>&nbsp;	public PMD getMetadata(@Nullable Object obj) {
<b class="fc"><i>107</i>&nbsp;		return obj != null ? getMetadata(getClass(obj)) : null;</b>
<i>108</i>&nbsp;	}
<i>109</i>&nbsp;
<i>110</i>&nbsp;	/**
<i>111</i>&nbsp;	 * Gets the persistence metadata associated with the given entity class.
<i>112</i>&nbsp;	 *
<i>113</i>&nbsp;	 * @param clazz the type to retrieve ClassMetadata for
<i>114</i>&nbsp;	 * @return the ClassMetadata or {@code null} if the type is not an Hibernate managed entity
<i>115</i>&nbsp;	 */
<i>116</i>&nbsp;	@Nullable
<i>117</i>&nbsp;	public abstract PMD getMetadata(@Nullable Class&lt;?&gt; clazz);
<i>118</i>&nbsp;
<i>119</i>&nbsp;	/**
<i>120</i>&nbsp;	 * Gets the unproxified type of the given object.
<i>121</i>&nbsp;	 *
<i>122</i>&nbsp;	 * @param proxy a persistable object or proxy
<i>123</i>&nbsp;	 * @return the true class of the instance
<i>124</i>&nbsp;	 */
<i>125</i>&nbsp;	@Nonnull
<i>126</i>&nbsp;	@SuppressWarnings(&quot;unchecked&quot;)
<i>127</i>&nbsp;	public &lt;T&gt; Class&lt;T&gt; getClass(@Nonnull Object proxy) {
<b class="fc"><i>128</i>&nbsp;		return getClass(proxy.getClass());</b>
<i>129</i>&nbsp;	}
<i>130</i>&nbsp;
<i>131</i>&nbsp;	/**
<i>132</i>&nbsp;	 * Gets the real type of the given class.
<i>133</i>&nbsp;	 *
<i>134</i>&nbsp;	 * @param clazz the type
<i>135</i>&nbsp;	 * @return the true class of the type
<i>136</i>&nbsp;	 */
<i>137</i>&nbsp;	@Nonnull
<i>138</i>&nbsp;	@SuppressWarnings(&quot;unchecked&quot;)
<i>139</i>&nbsp;	public &lt;T&gt; Class&lt;T&gt; getClass(@Nonnull Class&lt;?&gt; clazz) {
<b class="fc"><i>140</i>&nbsp;		while (isJavassistProxy(clazz)) {</b>
<b class="fc"><i>141</i>&nbsp;			clazz = clazz.getSuperclass();</b>
<i>142</i>&nbsp;		}
<b class="fc"><i>143</i>&nbsp;		return (Class&lt;T&gt;) clazz;</b>
<i>144</i>&nbsp;	}
<i>145</i>&nbsp;
<i>146</i>&nbsp;	/**
<i>147</i>&nbsp;	 * Returns the persistent class, or {@code null}.
<i>148</i>&nbsp;	 *
<i>149</i>&nbsp;	 * @param metadata the class metadata
<i>150</i>&nbsp;	 * @return the persistent class, or {@code null}
<i>151</i>&nbsp;	 */
<i>152</i>&nbsp;	@Nonnull
<i>153</i>&nbsp;	public abstract Class&lt;?&gt; getMappedClass(@Nonnull PMD metadata);
<i>154</i>&nbsp;
<i>155</i>&nbsp;	/**
<i>156</i>&nbsp;	 * Returns the entity name of the given class.&lt;br/&gt;
<i>157</i>&nbsp;	 * The entity name is the unique name of the entity in the meta-model or the simple class name if the type is not
<i>158</i>&nbsp;	 * known by the meta-model.
<i>159</i>&nbsp;	 *
<i>160</i>&nbsp;	 * @param clazz the type
<i>161</i>&nbsp;	 * @return the entity name of the class
<i>162</i>&nbsp;	 */
<i>163</i>&nbsp;	@Nonnull
<i>164</i>&nbsp;	public abstract String getEntityName(@Nonnull Class&lt;?&gt; clazz);
<i>165</i>&nbsp;
<i>166</i>&nbsp;	/**
<i>167</i>&nbsp;	 * Returns the name of the identifier property of the given type.&lt;br/&gt;
<i>168</i>&nbsp;	 * If the type has no identifier property e.g., it is not an entity, {@code null} is returned instead.
<i>169</i>&nbsp;	 *
<i>170</i>&nbsp;	 * @param clazz the type
<i>171</i>&nbsp;	 * @return the identifier property name or {@code null} if there is no identifier property
<i>172</i>&nbsp;	 */
<i>173</i>&nbsp;	@Nullable
<i>174</i>&nbsp;	protected abstract String getIdentifierPropertyName(@Nonnull Class&lt;?&gt; clazz);
<i>175</i>&nbsp;
<i>176</i>&nbsp;	/**
<i>177</i>&nbsp;	 * Attempts to get the identifier of the given object by using the provided persistence metadata or
<i>178</i>&nbsp;	 * {@link PropertyAccessor}.
<i>179</i>&nbsp;	 *
<i>180</i>&nbsp;	 * @param metadata the ClassMetadata of the object (may be null)
<i>181</i>&nbsp;	 * @param bean     the object
<i>182</i>&nbsp;	 * @return the identifier or {@code null} if the identifier cannot be retrieved or is {@code null}
<i>183</i>&nbsp;	 * @see #getIdentifierValue(PMD, Object)
<i>184</i>&nbsp;	 */
<i>185</i>&nbsp;	@Nullable
<i>186</i>&nbsp;	public abstract &lt;T&gt; Serializable getIdentifier(@Nonnull PMD metadata, @Nonnull T bean);
<i>187</i>&nbsp;
<i>188</i>&nbsp;	/**
<i>189</i>&nbsp;	 * Retrieves the identifier of the given object by using the provided persistence metadata or
<i>190</i>&nbsp;	 * {@link PropertyAccessor}.
<i>191</i>&nbsp;	 * If the identifier cannot be retrieved, an exception is thrown.
<i>192</i>&nbsp;	 *
<i>193</i>&nbsp;	 * @param metadata the ClassMetadata of the object (may be null)
<i>194</i>&nbsp;	 * @param bean     the object
<i>195</i>&nbsp;	 * @return the identifier or {@code null} if the identifier cannot be retrieved or is {@code null}
<i>196</i>&nbsp;	 * @see #getIdentifier(PMD, Object)
<i>197</i>&nbsp;	 */
<i>198</i>&nbsp;	@Nonnull
<i>199</i>&nbsp;	public &lt;T&gt; Serializable getIdentifierValue(@Nonnull PMD metadata, @Nonnull T bean) {
<b class="fc"><i>200</i>&nbsp;		Serializable identifier = getIdentifier(metadata, bean);</b>
<b class="fc"><i>201</i>&nbsp;		if (identifier == null) {</b>
<i>202</i>&nbsp;			// If the identifier of the database object is null, it is really null, which indicates a database problem, or it cannot be retrieved
<b class="fc"><i>203</i>&nbsp;			throw throwPropertyValueException(&quot;Cannot read identifier&quot;, bean);</b>
<i>204</i>&nbsp;		}
<b class="fc"><i>205</i>&nbsp;		return identifier;</b>
<i>206</i>&nbsp;	}
<i>207</i>&nbsp;
<i>208</i>&nbsp;	/**
<i>209</i>&nbsp;	 * Returns whether the Hibernate entity associated with the given metadata is versioned.&lt;br/&gt;
<i>210</i>&nbsp;	 *
<i>211</i>&nbsp;	 * @param metadata the metadata
<i>212</i>&nbsp;	 * @return {@link true}
<i>213</i>&nbsp;	 */
<i>214</i>&nbsp;	public abstract boolean isVersioned(@Nonnull PMD metadata);
<i>215</i>&nbsp;
<i>216</i>&nbsp;	/**
<i>217</i>&nbsp;	 * Returns the name of the property of the entity used for versioning (if available).
<i>218</i>&nbsp;	 *
<i>219</i>&nbsp;	 * @param metadata the metadata
<i>220</i>&nbsp;	 * @return the name of the version property or {@code null} if the entity is not versioned
<i>221</i>&nbsp;	 */
<i>222</i>&nbsp;	@Nullable
<i>223</i>&nbsp;	public abstract String getVersionPropertyName(@Nonnull PMD metadata);
<i>224</i>&nbsp;
<i>225</i>&nbsp;	/**
<i>226</i>&nbsp;	 * Retrieves the property of the given object.
<i>227</i>&nbsp;	 *
<i>228</i>&nbsp;	 * @param metadata     the ClassMetadata of the object (may be null)
<i>229</i>&nbsp;	 * @param bean         the object
<i>230</i>&nbsp;	 * @param propertyName the name of the property
<i>231</i>&nbsp;	 * @return the property
<i>232</i>&nbsp;	 * @see PropertyAccessor#getPropertyValue(String)
<i>233</i>&nbsp;	 */
<i>234</i>&nbsp;	@Nullable
<i>235</i>&nbsp;	public abstract Object getPropertyValue(@Nullable PMD metadata, @Nonnull Object bean, @Nonnull String propertyName);
<i>236</i>&nbsp;
<i>237</i>&nbsp;	/**
<i>238</i>&nbsp;	 * Sets the property of the given object.
<i>239</i>&nbsp;	 *
<i>240</i>&nbsp;	 * @param metadata     the ClassMetadata of the object (may be null)
<i>241</i>&nbsp;	 * @param bean         the object
<i>242</i>&nbsp;	 * @param propertyName the name of the property
<i>243</i>&nbsp;	 * @param value        the value to set
<i>244</i>&nbsp;	 * @see PropertyAccessor#setPropertyValue(String, Object)
<i>245</i>&nbsp;	 */
<i>246</i>&nbsp;	public abstract void setPropertyValue(@Nullable PMD metadata, @Nonnull Object bean, @Nonnull String propertyName, @Nullable Object value);
<i>247</i>&nbsp;
<i>248</i>&nbsp;	/**
<i>249</i>&nbsp;	 * Returns the property names of the given object.
<i>250</i>&nbsp;	 *
<i>251</i>&nbsp;	 * @param obj The object
<i>252</i>&nbsp;	 * @return The property names
<i>253</i>&nbsp;	 */
<i>254</i>&nbsp;	@Nonnull
<i>255</i>&nbsp;	public String[] getPropertyNames(@Nonnull Object obj) {
<b class="fc"><i>256</i>&nbsp;		Set&lt;String&gt; names = IntrospectorUtils.getDescriptorMap(getClass(obj)).keySet();</b>
<b class="fc"><i>257</i>&nbsp;		return names.toArray(new String[names.size()]);</b>
<i>258</i>&nbsp;	}
<i>259</i>&nbsp;
<i>260</i>&nbsp;	/**
<i>261</i>&nbsp;	 * Returns the type of the given named property.
<i>262</i>&nbsp;	 *
<i>263</i>&nbsp;	 * @param clazz        the class containing the property
<i>264</i>&nbsp;	 * @param propertyName the name of the property
<i>265</i>&nbsp;	 * @return the type of the property
<i>266</i>&nbsp;	 */
<i>267</i>&nbsp;	@Nonnull
<i>268</i>&nbsp;	public abstract Class&lt;?&gt; getPropertyType(@Nonnull Class&lt;?&gt; clazz, @Nonnull String propertyName);
<i>269</i>&nbsp;
<i>270</i>&nbsp;	/**
<i>271</i>&nbsp;	 * Returns a {@link PropertyAccessor} for accessing the objects properties.
<i>272</i>&nbsp;	 * &lt;p/&gt;
<i>273</i>&nbsp;	 * This method automatically detects the best strategy for accessing field values, which is either property access
<i>274</i>&nbsp;	 * (by using {@link org.springframework.beans.BeanWrapper BeanWrapper} or field access (by using
<i>275</i>&nbsp;	 * {@link org.springframework.beans.DirectFieldAccessor DirectFieldAccessor}.
<i>276</i>&nbsp;	 * &lt;p/&gt;
<i>277</i>&nbsp;	 * The decision is made by applying the following algorithm:&lt;br/&gt;
<i>278</i>&nbsp;	 * If there is persistence metadata available and
<i>279</i>&nbsp;	 * &lt;ul&gt;
<i>280</i>&nbsp;	 * &lt;li&gt;if the {@code javax.persistence.Id} annotation was found on a getter method or&lt;/li&gt;
<i>281</i>&nbsp;	 * &lt;li&gt;if the object is a proxy modified by Javassist and its but it is not accessible&lt;/li&gt;
<i>282</i>&nbsp;	 * &lt;/ul&gt;
<i>283</i>&nbsp;	 * the properties are access via getter and setter methods.&lt;br/&gt;
<i>284</i>&nbsp;	 * Otherwise the fields are accessed directly via reflection.
<i>285</i>&nbsp;	 * &lt;p/&gt;
<i>286</i>&nbsp;	 * &lt;b&gt;Note that if the given object is an uninitialized Javassist proxy, the object becomes initialized immediately
<i>287</i>&nbsp;	 * if the direct field access strategy is chosen.&lt;br/&gt;
<i>288</i>&nbsp;	 * Otherwise Hibernate will trigger the initialization automatically upon getter invocation as usual.&lt;/b&gt;
<i>289</i>&nbsp;	 *
<i>290</i>&nbsp;	 * @param metadata the class metadata
<i>291</i>&nbsp;	 * @param obj      the object
<i>292</i>&nbsp;	 * @return the property accessor
<i>293</i>&nbsp;	 */
<i>294</i>&nbsp;	@Nullable
<i>295</i>&nbsp;	public abstract PropertyAccessor getPropertyAccessor(@Nullable PMD metadata, @Nonnull Object obj);
<i>296</i>&nbsp;
<i>297</i>&nbsp;	/**
<i>298</i>&nbsp;	 * Returns the {@link AbstractPropertyAccessStrategy} to use for accessing properties of the given type.&lt;br/&gt;
<i>299</i>&nbsp;	 * If no strategy is defined for the type, a new one is created on-demand.
<i>300</i>&nbsp;	 *
<i>301</i>&nbsp;	 * @param clazz the type
<i>302</i>&nbsp;	 * @return the strategy to use
<i>303</i>&nbsp;	 * @see #createStrategy(Class)
<i>304</i>&nbsp;	 */
<i>305</i>&nbsp;	@Nonnull
<i>306</i>&nbsp;	public AbstractPropertyAccessStrategy getPropertyAccessStrategy(@Nonnull Class&lt;?&gt; clazz) {
<b class="fc"><i>307</i>&nbsp;		clazz = getClass(clazz);</b>
<b class="fc"><i>308</i>&nbsp;		AbstractPropertyAccessStrategy strategy = STRATEGY_MAP.get(clazz);</b>
<b class="fc"><i>309</i>&nbsp;		if (strategy == null) {</b>
<b class="fc"><i>310</i>&nbsp;			synchronized (STRATEGY_MAP) {</b>
<b class="fc"><i>311</i>&nbsp;				strategy = STRATEGY_MAP.get(clazz);</b>
<b class="fc"><i>312</i>&nbsp;				if (strategy == null) {</b>
<b class="fc"><i>313</i>&nbsp;					strategy = createStrategy(clazz);</b>
<b class="fc"><i>314</i>&nbsp;					STRATEGY_MAP.put(clazz, strategy);</b>
<i>315</i>&nbsp;				}
<b class="fc"><i>316</i>&nbsp;			}</b>
<i>317</i>&nbsp;		}
<b class="fc"><i>318</i>&nbsp;		return strategy;</b>
<i>319</i>&nbsp;	}
<i>320</i>&nbsp;
<i>321</i>&nbsp;	/**
<i>322</i>&nbsp;	 * Creates a new {@link AbstractPropertyAccessStrategy} instance for the given type.
<i>323</i>&nbsp;	 *
<i>324</i>&nbsp;	 * @param clazz the type
<i>325</i>&nbsp;	 * @return the strategy to use
<i>326</i>&nbsp;	 */
<i>327</i>&nbsp;	@Nonnull
<i>328</i>&nbsp;	protected abstract AbstractPropertyAccessStrategy createStrategy(@Nonnull Class&lt;?&gt; clazz);
<i>329</i>&nbsp;
<i>330</i>&nbsp;	/**
<i>331</i>&nbsp;	 * Checks if the named property is transient.
<i>332</i>&nbsp;	 *
<i>333</i>&nbsp;	 * @param obj the object to check
<i>334</i>&nbsp;	 * @param propertyName the name of the property
<i>335</i>&nbsp;	 * @return {@code true} if the property is transient, {@code false} otherwise
<i>336</i>&nbsp;	 */
<i>337</i>&nbsp;	public boolean isTransient(@Nonnull Object obj, @Nonnull String propertyName) {
<b class="fc"><i>338</i>&nbsp;		return getMetadata(obj) != null &amp;&amp; !getPropertyAccessStrategy(getClass(obj)).isProperty(propertyName);</b>
<i>339</i>&nbsp;	}
<i>340</i>&nbsp;
<i>341</i>&nbsp;	/**
<i>342</i>&nbsp;	 * Checks if the given object is a proxy maintained by the JPA provider.
<i>343</i>&nbsp;	 *
<i>344</i>&nbsp;	 * @param obj the object to check
<i>345</i>&nbsp;	 * @return {@code true} if the object is a JPA entity proxy, {@code false} otherwise
<i>346</i>&nbsp;	 * @see #isInitialized(Object)
<i>347</i>&nbsp;	 */
<i>348</i>&nbsp;	public abstract boolean isProxy(@Nullable Object obj);
<i>349</i>&nbsp;
<i>350</i>&nbsp;	/**
<i>351</i>&nbsp;	 * Check if the proxy or persistent collection is initialized.&lt;br/&gt;
<i>352</i>&nbsp;	 * If the objects is neither an entity nor a persistent collection e.g., a {@link String}, {@code true} is returned.
<i>353</i>&nbsp;	 *
<i>354</i>&nbsp;	 * @param obj the object to check
<i>355</i>&nbsp;	 * @return {@code true} if the argument is already initialized, or is not a proxy or collection
<i>356</i>&nbsp;	 */
<i>357</i>&nbsp;	public abstract boolean isInitialized(@Nullable Object obj);
<i>358</i>&nbsp;
<i>359</i>&nbsp;	/**
<i>360</i>&nbsp;	 * Checks if a certain property of a JPA entity proxy is uninitialized and the corresponding value of the transient
<i>361</i>&nbsp;	 * entity is {@code null}.&lt;br/&gt;
<i>362</i>&nbsp;	 * If the property of the persistent entity is uninitialized, it is assumed to be loaded lazily. Thus the property
<i>363</i>&nbsp;	 * of the transient entity must be {@code null}. If is is not, an exception is thrown.
<i>364</i>&nbsp;	 *
<i>365</i>&nbsp;	 * @param propertyName the name of the property to check
<i>366</i>&nbsp;	 * @param dbObj        the persistent entity
<i>367</i>&nbsp;	 * @param dbValue      the value of the persistent entity
<i>368</i>&nbsp;	 * @param trValue      the value of the transient entity
<i>369</i>&nbsp;	 * @return {@code true} if it is uninitialized, {@code false} otherwise
<i>370</i>&nbsp;	 * @throws RuntimeException if the property of the persistent entity is uninitialized but the transient value is not {@code null}
<i>371</i>&nbsp;	 * @see #throwLazyPropertyNotNullException(Object, Object, String)
<i>372</i>&nbsp;	 */
<i>373</i>&nbsp;	public abstract boolean isUninitialized(@Nonnull String propertyName, @Nonnull Object dbObj, @Nonnull Object dbValue, @Nullable Object trValue);
<i>374</i>&nbsp;
<i>375</i>&nbsp;	/**
<i>376</i>&nbsp;	 * Checks if the given class is a proxy of a persistent object that has been generated by using Javassist.
<i>377</i>&nbsp;	 *
<i>378</i>&nbsp;	 * @param clazz the class to check
<i>379</i>&nbsp;	 * @return {@code true} if the given class is a Javassist proxy.
<i>380</i>&nbsp;	 */
<i>381</i>&nbsp;	public boolean isJavassistProxy(@Nonnull Class&lt;?&gt; clazz) {
<b class="fc"><i>382</i>&nbsp;		return clazz.getSimpleName().contains(&quot;$$_javassist&quot;);</b>
<i>383</i>&nbsp;	}
<i>384</i>&nbsp;
<i>385</i>&nbsp;	/**
<i>386</i>&nbsp;	 * Checks if the given object is a persistent collection.
<i>387</i>&nbsp;	 *
<i>388</i>&nbsp;	 * @param obj the object to check
<i>389</i>&nbsp;	 * @return {@code true} if the object is a persistent collection, {@code false} otherwise
<i>390</i>&nbsp;	 * @see #isInitializedPersistentCollection(Object)
<i>391</i>&nbsp;	 */
<i>392</i>&nbsp;	public abstract boolean isPersistentCollection(@Nullable Object obj);
<i>393</i>&nbsp;
<i>394</i>&nbsp;	/**
<i>395</i>&nbsp;	 * Checks if the given object is an initialized persistent collection.
<i>396</i>&nbsp;	 *
<i>397</i>&nbsp;	 * @param obj the object to check
<i>398</i>&nbsp;	 * @return {@code true} if the object is an initialized persistent collection, {@code false} otherwise
<i>399</i>&nbsp;	 * @see #isPersistentCollection(Object)
<i>400</i>&nbsp;	 */
<i>401</i>&nbsp;	public abstract boolean isInitializedPersistentCollection(@Nullable Object obj);
<i>402</i>&nbsp;
<i>403</i>&nbsp;	/**
<i>404</i>&nbsp;	 * Return the persistent instance of the given entity class with the given identifier, or {@code null} if there is
<i>405</i>&nbsp;	 * no such persistent instance.&lt;br/&gt;
<i>406</i>&nbsp;	 * If the instance is already associated with the persistence context, return that instance.
<i>407</i>&nbsp;	 * This method never returns an uninitialized instance.
<i>408</i>&nbsp;	 *
<i>409</i>&nbsp;	 * @param clazz the persistent class
<i>410</i>&nbsp;	 * @param id    the identifier
<i>411</i>&nbsp;	 * @return the persistent instance
<i>412</i>&nbsp;	 */
<i>413</i>&nbsp;	@Nullable
<i>414</i>&nbsp;	public abstract &lt;T&gt; T find(@Nonnull Class&lt;T&gt; clazz, @Nonnull Serializable id);
<i>415</i>&nbsp;
<i>416</i>&nbsp;	/**
<i>417</i>&nbsp;	 * Force the current persistence context to flush.
<i>418</i>&nbsp;	 * &lt;p/&gt;
<i>419</i>&nbsp;	 * &lt;i&gt;Flushing&lt;/i&gt; is the process of synchronizing the underlying persistent store with persistable state held in
<i>420</i>&nbsp;	 * memory.
<i>421</i>&nbsp;	 */
<i>422</i>&nbsp;	public abstract void flush();
<i>423</i>&nbsp;
<i>424</i>&nbsp;	/**
<i>425</i>&nbsp;	 * Persists the given transient instance.
<i>426</i>&nbsp;	 *
<i>427</i>&nbsp;	 * @param obj a transient instance of a persistent class
<i>428</i>&nbsp;	 * @return the generated identifier
<i>429</i>&nbsp;	 */
<i>430</i>&nbsp;	@Nonnull
<i>431</i>&nbsp;	public abstract &lt;K&gt; K persist(@Nonnull Object obj);
<i>432</i>&nbsp;
<i>433</i>&nbsp;	/**
<i>434</i>&nbsp;	 * Throws an exception indicating that the object must be saved manually before continuing.
<i>435</i>&nbsp;	 *
<i>436</i>&nbsp;	 * @param object the object
<i>437</i>&nbsp;	 * @return nothing
<i>438</i>&nbsp;	 * @throws RuntimeException the exception
<i>439</i>&nbsp;	 */
<i>440</i>&nbsp;	public abstract RuntimeException throwUnsavedTransientInstanceException(@Nonnull Object object);
<i>441</i>&nbsp;
<i>442</i>&nbsp;	/**
<i>443</i>&nbsp;	 * Throws an exception indicating that the object has no valid identifier.
<i>444</i>&nbsp;	 *
<i>445</i>&nbsp;	 * @param object the object
<i>446</i>&nbsp;	 * @return nothing
<i>447</i>&nbsp;	 * @throws RuntimeException the exception
<i>448</i>&nbsp;	 */
<i>449</i>&nbsp;	public abstract RuntimeException throwNullIdentifierException(@Nonnull Object object);
<i>450</i>&nbsp;
<i>451</i>&nbsp;	/**
<i>452</i>&nbsp;	 * Throws an exception when a lazy property holds a value while {@code null} was expected.
<i>453</i>&nbsp;	 *
<i>454</i>&nbsp;	 * @param trValue      the transient value (that should be {@code null})
<i>455</i>&nbsp;	 * @param dbObj        the persistent entity
<i>456</i>&nbsp;	 * @param propertyName the name of the property
<i>457</i>&nbsp;	 * @return nothing
<i>458</i>&nbsp;	 * @throws RuntimeException the exception
<i>459</i>&nbsp;	 */
<i>460</i>&nbsp;	public abstract RuntimeException throwLazyPropertyNotNullException(@Nonnull Object trValue, @Nonnull Object dbObj, @Nonnull String propertyName);
<i>461</i>&nbsp;
<i>462</i>&nbsp;	/**
<i>463</i>&nbsp;	 * Throws an exception when an optimistic locking conflict occurs.
<i>464</i>&nbsp;	 *
<i>465</i>&nbsp;	 * @param dbValue    the persistent value causing the conflict
<i>466</i>&nbsp;	 * @param identifier the identifier of the entity
<i>467</i>&nbsp;	 * @return nothing
<i>468</i>&nbsp;	 * @throws RuntimeException the exception
<i>469</i>&nbsp;	 */
<i>470</i>&nbsp;	public abstract RuntimeException throwOptimisticLockException(@Nonnull Object dbValue, @Nonnull Serializable identifier);
<i>471</i>&nbsp;
<i>472</i>&nbsp;	/**
<i>473</i>&nbsp;	 * Throws an exception when an entity reference is accessed but the entity does not exist.
<i>474</i>&nbsp;	 *
<i>475</i>&nbsp;	 * @param identifier the identifier of the entity attempted to retrieve
<i>476</i>&nbsp;	 * @param trObj      the transient object
<i>477</i>&nbsp;	 * @return nothing
<i>478</i>&nbsp;	 * @throws RuntimeException the exception
<i>479</i>&nbsp;	 */
<i>480</i>&nbsp;	public abstract RuntimeException throwEntityNotFoundException(@Nonnull Serializable identifier, @Nonnull Object trObj);
<i>481</i>&nbsp;
<i>482</i>&nbsp;	/**
<i>483</i>&nbsp;	 * Throws an exception when a property is not accessible or holds an unexpected value.
<i>484</i>&nbsp;	 *
<i>485</i>&nbsp;	 * @param message the detail message
<i>486</i>&nbsp;	 * @param bean    the bean caused the exception
<i>487</i>&nbsp;	 * @return nothing
<i>488</i>&nbsp;	 * @throws RuntimeException the exception
<i>489</i>&nbsp;	 */
<i>490</i>&nbsp;	public abstract RuntimeException throwPropertyValueException(@Nonnull String message, @Nonnull Object bean);
<i>491</i>&nbsp;
<i>492</i>&nbsp;	/**
<i>493</i>&nbsp;	 * Obtains the current persistence context.
<i>494</i>&nbsp;	 *
<i>495</i>&nbsp;	 * @return the persistence context to use
<i>496</i>&nbsp;	 */
<i>497</i>&nbsp;	@Nonnull
<i>498</i>&nbsp;	public abstract PC getPersistenceContext();
<i>499</i>&nbsp;}
</div>
</div>

<div class="footer">
    
    <div style="float:right;">generated on 2013-07-31 23:31</div>
</div>
</body>
</html>
